import axios from 'axios';

import { tipsMessage, hasKey, _getHttpCodeMsg, httpConfig, clearLogin, errCode, errCodeFn, errorResponse } from './util'

/*const addErrorLog = errorInfo => {
    const {
        statusText, status, request: {
            responseURL
        }
    } = errorInfo
    let info = {
        type: 'ajax',
        code: status,
        mes: statusText,
        url: responseURL
    }
    if (!responseURL.includes('save_error_logger')) store.dispatch('addErrorLog', info)
}*/

// 超时配置
const { timeout, retry, retryDelay } = httpConfig;
if(timeout) axios.defaults.timeout = timeout;      
if(retry) axios.defaults.retry = retry;    
if(retryDelay) axios.defaults.retryDelay = retryDelay;

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

class HttpRequest {
    constructor(baseUrl = baseURL) {
        this.baseUrl = baseUrl
        this.queue = {}
    }
    getInsideConfig() {
        const config = {
            baseURL: this.baseUrl,
            headers: {
                //
            },
            /*cancelToken: new CancelToken(c => { 
                Vue.$httpRequestList.push(c);
            })*/
            // cancelToken: source.token,
        }
        return config
    }
    destroy(url) {
        delete this.queue[url];
    }
    interceptors(instance, url) {
        // 请求拦截
        instance.interceptors.request.use(config => {
            config.cancelToken = new CancelToken(c => { 
                if(hasKey(this.queue,url)) {
                    c(url);
                }else{
                    this.queue[url] = true;
                    // this.queue[url] = c;
                };
            })
            
            /*config.cancelToken = new CancelToken(c => { 
                this.queue[url] = c;
            })
            if(hasKey(this.queue,url)) {
                this.queue[url](url);
            };*/
            return config
        }, error => {
            //return Promise.reject(error)
        })

        // 响应拦截
        instance.interceptors.response.use(res => {
            this.destroy(url);
            const {
                data, status
            } = res; //200
            const code = httpConfig.code;
            
            if(code && data[code]){ //返回数据中有code和msg
                let resultMsg = httpConfig.msg || "";
                let dataCode = httpConfig.dataCode || "";

                if (errCode.sucess && data[code] == errCode.sucess) { //成功
                    let resultData = dataCode ? data[dataCode] : data;
                    return resultData || data;
                } else if (errCode.invalid && data[code]==errCode.invalid) { //失效
                    clearLogin && clearLogin(res);
                    return false;
                } else if(errCodeFn){ //可以根据state判断状态，返回数据
                    return errCodeFn(data,status);
                } else if(data[resultMsg]) {
                    tipsMessage(data[resultMsg]);
                    return false;
                } else{
                    console.log('must code and msg',res);
                };
            }else if(errCodeFn){ //可以根据state判断状态，返回数据
                console.log('no code',res);
                return errCodeFn(data,status);
            }else{
                console.log('must errCodeFn',res);
            };
        }, (error) => {
            let resMessage = "";
            this.destroy(url);
            if(errorResponse) return errorResponse(error);
            if(error && error.response){
                // const { response: { statusText, status }, config } = JSON.parse(JSON.stringify(error));
                const errorInfo = JSON.parse(JSON.stringify(error));
                // if(config) errorInfo.request = { responseURL: config.url };

                // let msg = errorInfo.statusText || error.message || '系统异常，请稍后重试';
                let msg = "";
                let status = errorInfo.response ? errorInfo.response.status : error.response.status || '';
                //error 与 error.response 返回结果有些不一样

                if(status) msg = _getHttpCodeMsg(status);
                else {
                    console.log('no status：',errorInfo,error.response);
                    let response = errorInfo.response || error.response;
                    msg = response.statusText || response.message || '系统异常，请稍后重试';
                };
                console.error('系统异常', errorInfo, error.response, error.message,error.code);
                resMessage = msg;
            }else if(error.code == 'ECONNABORTED' && ~error.message.indexOf('timeout')){
                const errConfig = error.config || {};
                console.log('系统请求超时',error,error.message,error.code,error.response,errConfig);
                if(errConfig.retry){
                    errConfig.__retryCount = errConfig.__retryCount || 0;
                    errConfig.__retryCount += 1;
                    if(errConfig.__retryCount < errConfig.retry) {
                        return this.request(errConfig);
                    }else resMessage = "系统请求超时，请稍后重试";
                }else resMessage = "系统请求超时，请稍后重试";
            }else if(axios.isCancel(error)) {
                console.log('中断请求',error,error.message,error.code)
                // resMessage = "中断请求"
            }else{
                //Network Error
                console.log('连接到服务器失败',error,error.message,error.code,error.response);
                resMessage = "连接到服务器失败";
            };
            
            if(resMessage) tipsMessage(resMessage);
            return false;
        })
    }
    request(options) {
        const instance = axios.create()
        options = Object.assign(this.getInsideConfig(), options);
        //console.log(options);
        this.interceptors(instance, options.url)
        // console.log('axios.defaults',axios.defaults);
        return instance(options)
    }
}
export default HttpRequest;

/**
 * 异步缓存：不停的刷新，查看数据的更新，非必要做
 * 中断请求：客户端中断请求后，服务器是否中断，中断后如何处理
 * 全局提示：出现多个接口错误连续弹出信息
 * 重复提交：按钮加loading状态
 */
/*
中断请求：
- 防止重复提交：只要上一个请求没有返回结果，再次请求的话，就会取消上一个请求，执行当前请求

axios: cancelToken: _this.source.token,
this.source.cancel();

https://www.jianshu.com/p/12362b75ea4b
https://www.jianshu.com/p/1662e2524c64
 */
